//===============================================================================
// Microsoft patterns & practices
// Guidance Explorer Offline Client
//===============================================================================
// Copyright  Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================



using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;
using GuidanceExplorer.Model;

namespace GuidanceExplorer.Controls
{
    /// <summary>
    /// Represents a guidance item within a list box.
    /// </summary>
    public class GuidanceItemListViewItem : ListViewItem
    {
        #region Static Part

        /// <summary>
        /// Factory.
        /// </summary>
        /// <returns></returns>
        /// <param name="item">The guidance item to represent.</param>
        /// <param name="columns">The columns for the list.</param>
        public static GuidanceItemListViewItem New(GuidanceItem item, ColumnCollection columns)
        {
            return new GuidanceItemListViewItem(item, columns);
        }

        /// <summary>
        /// Return a string[] that matches the order of the columns in the list.
        /// </summary>
        /// <param name="item">The item to process.</param>
        /// <param name="columns">The collection of the columns.</param>
        /// <returns>A new string array.</returns>
        private static string[] GetSubItems(GuidanceItem item, ColumnCollection columns)
        {
            PropertyDescriptorCollection propertyDescriptors = TypeDescriptor.GetProperties(item.GetType());

            SortedList<int, Column> sortedCols = new SortedList<int, Column>(columns.Count);
            foreach (Column column in columns.Values)
            {
                if (column.Visible)
                {
                    sortedCols.Add(column.Position, column);
                }
            }

            string[] values = new string[sortedCols.Count];
            int index = 0;

            foreach (Column column in sortedCols.Values)
            {
                string value = string.Empty;
                bool propertyFound = false;

                //Find the property in the type.
                PropertyDescriptor descriptor = propertyDescriptors[column.Source];
                if (descriptor != null)
                {
                    value = (string)descriptor.GetValue(item);
                    propertyFound = true;
                }

                //If the property was not found, then use the custom data.
                if (!propertyFound)
                {
                    value = item[column.Source];
                }

                //Set the value of the array.
                values[index++] = value;
            }
            
            return values;
        }

        #endregion

        #region Private members

        /// <summary>
        /// Reference to the GuidanceItem of the model.
        /// </summary>
        private GuidanceItem _item;

        #endregion

        #region Constructors

        /// <summary>
        /// Private constructor.
        /// </summary>
        /// <param name="item">The guidance item to represent.</param>
        /// <param name="columns">The columns for the list.</param>
        private GuidanceItemListViewItem(GuidanceItem item, ColumnCollection columns)
            : base(GetSubItems(item, columns))
        {
            _item = item;
            Name = _item.Id;
        }

        #endregion

        #region Public Properties

        /// <summary>
        /// Reference to the GuidanceItem of the model.
        /// </summary>
        public GuidanceItem GuidanceItem
        {
            get { return _item; }
            set { _item = value; }
        }

        #endregion

        #region Public methods

        /// <summary>
        /// Get the GuidanceItemFileReference for this guidance.
        /// </summary>
        /// <param name="guidance"></param>
        /// <returns></returns>
        public GuidanceItemFileReference GetGuidanceItemFileReference(Guidance guidance)
        {
            GuidanceItemFileReference gifr = GuidanceItem as GuidanceItemFileReference;
            if (gifr != null)
            {
                return gifr;
            }
            else
            {
                return guidance.GetGuidanceItemFileReference(GuidanceItem);
            }
        }

        #endregion
    }
}

